package behavioral_pattern.visitor_pattern;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * @version: 1.0
 * @Description: TODO
 * @author: zZmH
 * @date: 2020/12/09 17:26
 */


public class VisitorPattern {
    public static void main(String[] args) {
        ObjectStructure objectStructure = new ObjectStructure();
        objectStructure.add(new ConcreteElementA());
        objectStructure.add(new ConcreteElementB());
        objectStructure.add(new ConcreteElementA());

        objectStructure.accept(new ConcreteVisitorA());
        System.out.println("------------");
        objectStructure.accept(new ConcreteVisitorB());

    }
}

//对象结构角色
class ObjectStructure {
    private List<Element> list = new ArrayList<Element>();
    public void accept(Visitor visitor) {
        for (Element element : list) {
            element.accept(visitor);
        }
    }
    public void add(Element element) {
        list.add(element);
    }
    public void remove(Element element) {
        list.remove(element);
    }
}
//抽象元素类
interface Element {
    void accept(Visitor visitor);
}
class ConcreteElementA implements Element{

    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
    public String operationA() {
        return "具体元素A的操作。";
    }
}
class ConcreteElementB implements Element{

    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
    public String operationB() {
        return "具体元素B的操作。";
    }
}

interface Visitor{
    void visit(ConcreteElementA element);

    void visit(ConcreteElementB element);
}
class ConcreteVisitorA implements Visitor {
    public void visit(ConcreteElementA element) {
        System.out.println("具体访问者A访问-->" + element.operationA());
    }
    public void visit(ConcreteElementB element) {
        System.out.println("具体访问者A访问-->" + element.operationB());
    }
}
class ConcreteVisitorB implements Visitor {
    public void visit(ConcreteElementA element) {
        System.out.println("具体访问者B访问-->" + element.operationA());
    }
    public void visit(ConcreteElementB element) {
        System.out.println("具体访问者B访问-->" + element.operationB());
    }
}